﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Xugege.AbpExtension.Application.Extension.DataDictionary.Dto;
using Abp.Extensions;
using Castle.Core.Internal;
using Xugege.AbpExtension.Core.Extension.DataManager;
using Abp.UI;
using Xugege.AbpExtension.Com.Dto;

namespace Xugege.AbpExtension.Application.Extension.DataDictionary
{
    public class DictionaryService : AbpZeroTemplateAppServiceBase, IDictionaryService
    {

        private readonly IRepository<DataDictionaryCategory, int> _dictionaryCategory;
        private readonly IRepository<Core.Extension.DataManager.DataDictionary, long> _dataDictionary;
        private readonly DictionaryHelper _dictionaryHelper;

        public DictionaryService(
            IRepository<DataDictionaryCategory, int> dictionaryCategory,
            IRepository<Core.Extension.DataManager.DataDictionary, long> dataDictionary,
            DictionaryHelper dictionaryHelper)
        {
            _dictionaryHelper = dictionaryHelper;
            _dictionaryCategory = dictionaryCategory;
            _dataDictionary = dataDictionary;
        }

        public async Task<IList<JsTreeDto<DictionaryOutputDto>>> GetDictionariesByCategory(DictionaryInputDto input)
        {

            IList<DictionaryOutputDto> result = new List<DictionaryOutputDto>();

            if (input.CategoryCode.IsNullOrEmpty())
            {
                throw new Exception(L("ParamError"));
            }
            var allList = _dataDictionary.GetAll();
            if (input.CategoryCode == "-1")
            {
                //查询所有
                //_dictionaryHelper.CreateDictionaryTreeList((await _dataDictionary.GetAll().ToListAsync()).MapTo<IList<DictionaryOutputDto>>(), category.LevelRule)

                var categoryCodes = _dictionaryCategory.GetAll().Where(m=>m.Enabled).Distinct().ToList();

                foreach (var code in categoryCodes)
                {

                    //var category = await _dictionaryCategory.GetAll().FirstOrDefaultAsync(m => m.CategoryCode.Equals(code));
                    //if (code != null)
                    //{
                        var dicList = await allList.Where(m => m.CategoryCode == code.CategoryCode).ToListAsync();
                        result = CreateOutput(result, dicList, code);
                    //}
                }
            }
            else
            {
                //类别
                var category = await _dictionaryCategory.GetAll().FirstOrDefaultAsync(m => m.CategoryCode.Equals(input.CategoryCode));
                if (category != null)
                {
                    var dicList = await allList.Where(m => m.CategoryCode == category.CategoryCode).ToListAsync();
                    result = CreateOutput(result, dicList, category);
                }

            }


            return Dictionary2JsTree(result);
        }




        public async Task<IList<JsTreeDto<DictionaryOutputDto>>> GetDictionariesByCategoryNew(DictionaryInputDto input)
        {

            IList<DictionaryOutputDto> result = new List<DictionaryOutputDto>();

            if (input.CategoryCode.IsNullOrEmpty())
            {
                throw new Exception(L("ParamError"));
            }
            var allList = _dataDictionary.GetAll();
            if (input.CategoryCode == "-1")
            {
                //查询所有
                //_dictionaryHelper.CreateDictionaryTreeList((await _dataDictionary.GetAll().ToListAsync()).MapTo<IList<DictionaryOutputDto>>(), category.LevelRule)

                var categoryCodes = await allList.Select(m => m.CategoryCode).Distinct().ToListAsync();

                foreach (var code in categoryCodes)
                {

                    var category = await _dictionaryCategory.GetAll().FirstOrDefaultAsync(m => m.CategoryCode.Equals(code));
                    if (category != null)
                    {
                        var dicList = await allList.Where(m => m.CategoryCode == code).ToListAsync();
                        result = CreateOutput(result, dicList, category);
                    }
                }
            }
            else
            {
                //类别
                var category = await _dictionaryCategory.GetAll().FirstOrDefaultAsync(m => m.CategoryCode.Equals(input.CategoryCode));
                if (category != null)
                {
                    var dicList = await allList.Where(m => m.CategoryCode == category.CategoryCode).ToListAsync();
                    result = CreateOutput(result, dicList, category);
                }

            }


            return Dictionary2JsTree(result);
        }
        #region
        private IList<DictionaryOutputDto> CreateOutput(IList<DictionaryOutputDto> result, List<Core.Extension.DataManager.DataDictionary> allList, DataDictionaryCategory category)
        {
            if (category != null)
            {
                DictionaryOutputDto parent = new DictionaryOutputDto()
                {
                    Id = 0,
                    ParentCode = null,
                    Code = string.Empty,
                    CategoryCode = category.CategoryCode,
                    CategoryName = category.Name,
                    Name = category.Name,
                    Value = category.Name,
                    LevelRule = category.LevelRule
                };
                result.Add(parent);
                IList<DictionaryOutputDto> temp = _dictionaryHelper.CreateDictionaryTreeList(
                        allList
                        .MapTo<IList<DictionaryOutputDto>>(),
                            category.LevelRule);

                temp.ForEach((m) =>
                {
                    m.CategoryName = category.Name;
                    m.LevelRule = category.LevelRule;
                    m.ParentCode = string.IsNullOrEmpty(m.ParentCode) ? category.CategoryCode : m.ParentCode;
                });
                result = result.Concat(temp).ToList();
            }

            return result;
        }

        private IList<JsTreeDto<DictionaryOutputDto>> Dictionary2JsTree(IList<DictionaryOutputDto> dics)
        {
            IList<JsTreeDto<DictionaryOutputDto>> trees = new List<JsTreeDto<DictionaryOutputDto>>();
            foreach (DictionaryOutputDto dto in dics)
            {
                trees.Add(new JsTreeDto<DictionaryOutputDto>()
                {
                    Id = dto.CategoryCode + dto.Code,
                    Parent = (!string.IsNullOrEmpty(dto.ParentCode) ? dto.ParentCode : "#"),
                    Text = dto.Name,
                    Value = dto.Value,
                    Data = dto

                });
            }
            return trees;
        }
        #endregion
        /// <summary>
        /// 添加或修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<DictionaryOutputDto> Update(DictionaryInputDto input)
        {
            input.TenantId = GetCurrentTenant().Id;
            if (input.Id.HasValue && input.Id.Value != 0)
            {
                //编辑
                var dicOfDb = await _dataDictionary.GetAsync(input.Id.Value);
                if (dicOfDb == null)
                {
                    throw new UserFriendlyException("对象不存在");
                }
                dicOfDb.Name = input.Name;
                dicOfDb.Value = input.Value;
                dicOfDb.Code = input.Code;
                dicOfDb.TenantId = input.TenantId;
                dicOfDb.IsDefault = input.IsDefault;
                if (input.IsDefault)
                {
                    var categoryDictionary =
                        await _dataDictionary.GetAll()
                            .Where(m => m.IsDefault && dicOfDb.CategoryCode == m.CategoryCode)
                            .ToListAsync();
                    foreach (var dictionary in categoryDictionary)
                    {
                        dictionary.IsDefault = false;
                        await _dataDictionary.UpdateAsync(dictionary);
                    }
                }
                return (await _dataDictionary.UpdateAsync(dicOfDb)).MapTo<DictionaryOutputDto>();
            }
            else
            {
                //添加
                if (input.CategoryCode.IsNullOrEmpty())
                {
                    throw new UserFriendlyException(L("ParamError"));
                }
                var dbData = input.MapTo<Core.Extension.DataManager.DataDictionary>();
                if (input.IsDefault)
                {
                    var categoryDictionary =
                        await _dataDictionary.GetAll()
                            .Where(m => m.IsDefault && dbData.CategoryCode == m.CategoryCode)
                            .ToListAsync();
                    foreach (var dictionary in categoryDictionary)
                    {
                        dictionary.IsDefault = false;
                        await _dataDictionary.UpdateAsync(dictionary);
                    }
                }
                return (await _dataDictionary.InsertAsync(dbData))
                    .MapTo<DictionaryOutputDto>();
            }
        }

        public async Task<long> Delete(DictionaryInputDto input)
        {
            if (!input.Id.HasValue)
            {
                throw new UserFriendlyException(L("ParamError"));
            }
            await _dataDictionary.DeleteAsync(input.Id.Value);
            return input.Id.Value;
        }

        public async Task<IList<DictionaryOutputDto>> GetDictionaries(DictionaryInputDto input)
        {
            if (input.CategoryCode.IsNullOrEmpty())
            {
                throw new UserFriendlyException(L("ParamError"));
            }

            return (await _dataDictionary.GetAll().Where(m => m.CategoryCode == input.CategoryCode).ToListAsync())
                .MapTo<IList<DictionaryOutputDto>>();
        }

    }
}
